package org.smarthings.things.management.impl.metadata.provider;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
import org.smarthings.things.management.metadata.ThingDataType;
import org.smarthings.things.management.metadata.ThingPropertyMetadata;
import org.smarthings.things.management.metadata.provider.ThingPropertyMetadataProvider;

@Component(immediate = true)
@Service(ThingPropertyMetadataProvider.class)
public class DefaultThingPropertyMetadataProvider implements ThingPropertyMetadataProvider {

	private Map<String, ThingPropertyMetadata> properties;

	public DefaultThingPropertyMetadataProvider() {
		properties = new HashMap<String, ThingPropertyMetadata>(2);
		properties.put("temperatureMesurement", new ThingPropertyMetadata(
				"Current temperature measured by the object in the specificed unit of measure.", "degrees Celsius",
				ThingDataType.DOUBLE, "-10.0", "40.0", "RE"));
		properties.put("humidityMeasurement", new ThingPropertyMetadata(
				"Current relative Humidity measured by the object in the specificed unit of measure.", "%",
				ThingDataType.DOUBLE, "0.0", "75.0", "RE"));
		properties.put("pressureMeasurement", new ThingPropertyMetadata(
				"Current pressure measured by the object in the specificed unit of measure.", "Pa",
				ThingDataType.DOUBLE, "0.0", "75.0", "RE"));
		properties.put("illuminanceMeasurement", new ThingPropertyMetadata(
				"Current illumininance level measured by the object in the specificed unit of measure.", "Lum",
				ThingDataType.DOUBLE, "0.0", "75.0", "RE"));		
		properties.put("heatMeasurement", new ThingPropertyMetadata(
				"Current heat consumption measured by the object in the specificed unit of measure.", "J",
				ThingDataType.DOUBLE, "0.0", "75.0", "RE"));
		properties.put("energyMeasurement", new ThingPropertyMetadata(
				"Current energy consumption measured by the object in the specificed unit of measure.", "kW",
				ThingDataType.DOUBLE, "0.0", "75.0", "RE"));
		properties.put("waterMeasurement", new ThingPropertyMetadata(
				"Current water consumption measured by the object in the specificed unit of measure.", "m^3",
				ThingDataType.DOUBLE, "0.0", "75.0", "RE"));
		properties.put("gasMeasurement", new ThingPropertyMetadata(
				"Current gas consumption measured by the object in the specificed unit of measure.","m^3",
				ThingDataType.DOUBLE, "0.0", "75.0", "RE"));
		
		properties.put("heatMeasurementAverage", new ThingPropertyMetadata(
				"Average heat consumption measured by the object in the specificed unit of measure.", "J",
				ThingDataType.DOUBLE, "0.0", "75.0", "RE"));
		properties.put("energyMeasurementAverage", new ThingPropertyMetadata(
				"Average energy consumption measured by the object in the specificed unit of measure.", "kW",
				ThingDataType.DOUBLE, "0.0", "75.0", "RE"));
		properties.put("waterMeasurementAverage", new ThingPropertyMetadata(
				"Average water consumption measured by the object in the specificed unit of measure.", "m^3",
				ThingDataType.DOUBLE, "0.0", "75.0", "RE"));
		properties.put("gasMeasurementAverage", new ThingPropertyMetadata(
				"Average gas consumption measured by the object in the specificed unit of measure.","m^3",
				ThingDataType.DOUBLE, "0.0", "75.0", "RE"));
		
		properties.put("heatMeasurementTotal", new ThingPropertyMetadata(
				"Accumulated heat consumption measured by the device in the specificed unit of measure.", "Jh",
				ThingDataType.DOUBLE, "0.0", "75.0", "RE"));
		properties.put("energyMeasurementTotal", new ThingPropertyMetadata(
				"Accumulated energy consumption measured by the device in the specificed unit of measure.", "kWh",
				ThingDataType.DOUBLE, "0.0", "75.0", "RE"));
		properties.put("waterMeasurementTotal", new ThingPropertyMetadata(
				"Accumulated water consumption measured by the device in the specificed unit of measure.", "m^3h",
				ThingDataType.DOUBLE, "0.0", "75.0", "RE"));
		properties.put("gasMeasurementTotal", new ThingPropertyMetadata(
				"Accumulated gas consumption measured by the device in the specificed unit of measure.","m^3h",
				ThingDataType.DOUBLE, "0.0", "75.0", "RE"));
		
		properties.put("temperatureMeasurementHigh", new ThingPropertyMetadata(
				"Critically high current temperature measured by the device in the specificed unit of measure.",  null,
				ThingDataType.BOOLEAN,null, null, "RE"));
		properties.put("humidityMeasurementHigh", new ThingPropertyMetadata(
				"Critically high current humidity measured by the device in the specificed unit of measure.",  null,
				ThingDataType.BOOLEAN, null, null, "RE"));
		properties.put("heatMeasurementHigh", new ThingPropertyMetadata(
				"Critically high current heat consumption measured by the device in the specificed unit of measure.",  null,
				ThingDataType.BOOLEAN,null, null, "RE"));
		properties.put("energyMeasurementHigh", new ThingPropertyMetadata(
				"Critically high current energy consumption measured by the device in the specificed unit of measure.", null,
				ThingDataType.BOOLEAN, null, null, "RE"));
		properties.put("waterMeasurementHigh", new ThingPropertyMetadata(
				"Critically high current consumption measured by the device in the specificed unit of measure.", null,
				ThingDataType.BOOLEAN, null, null, "RE"));
		properties.put("gasMeasurementHigh", new ThingPropertyMetadata(
				"Critically high current gas consumption measured by the device in the specificed unit of measure.", null,
				ThingDataType.BOOLEAN, null, null, "RE"));
		properties.put("pressureMeasurementLow", new ThingPropertyMetadata(
				"Critically high pressure measured by the device in the specificed unit of measure.",  null,
				ThingDataType.BOOLEAN,null, null, "RE"));
		
		properties.put("temperatureMeasurementLow", new ThingPropertyMetadata(
				"Critically low current temperature measured by the device in the specificed unit of measure.", null,
				ThingDataType.BOOLEAN,null, null, "RE"));
		properties.put("humidityMeasurementLow", new ThingPropertyMetadata(
				"Critically low current humidity measured by the device in the specificed unit of measure.",  null,
				ThingDataType.BOOLEAN, null, null, "RE"));
		properties.put("pressureMeasurementLow", new ThingPropertyMetadata(
				"Critically low pressure measured by the device in the specificed unit of measure.", null,
				ThingDataType.BOOLEAN,null, null, "RE"));
		
		properties.put("temperatureMesurementHighThreshold", new ThingPropertyMetadata(
				"Threshold for signaling high temperature measured by the object in the specificed unit of measure.", "degrees Celsius",
				ThingDataType.DOUBLE, "-10.0", "40.0", "RW"));
		properties.put("humidityMeasurementHighThreshold", new ThingPropertyMetadata(
				"Threshold for signaling high relative measured by the object in the specificed unit of measure.", "%",
				ThingDataType.DOUBLE, "0.0", "75.0", "RW"));
		properties.put("pressureMeasurementHighThreshold", new ThingPropertyMetadata(
				"Threshold for signaling high pressure measured by the object in the specificed unit of measure.", "Pa",
				ThingDataType.DOUBLE, "0.0", "75.0", "RW"));
		properties.put("heatMeasurementHighThreshold", new ThingPropertyMetadata(
				"Threshold for signaling high heat consumption measured by the object in the specificed unit of measure.", "J",
				ThingDataType.DOUBLE, "0.0", "75.0", "RW"));
		properties.put("energyMeasurementHighThreshold", new ThingPropertyMetadata(
				"Threshold for signaling high energy consumption measured by the object in the specificed unit of measure.", "kW",
				ThingDataType.DOUBLE, "0.0", "75.0", "RW"));
		properties.put("waterMeasurementHighThreshold", new ThingPropertyMetadata(
				"Threshold for signaling high water consumption measured by the object in the specificed unit of measure.", "m^3",
				ThingDataType.DOUBLE, "0.0", "75.0", "RW"));
		properties.put("gasMeasurementHighThreshold", new ThingPropertyMetadata(
				"Threshold for signaling high gas consumption measured by the object in the specificed unit of measure.","m^3",
				ThingDataType.DOUBLE, "0.0", "75.0", "RW"));
		
		properties.put("temperatureMesurementLowThreshold", new ThingPropertyMetadata(
				"Threshold for signaling low temperature measured by the object in the specificed unit of measure.", "degrees Celsius",
				ThingDataType.DOUBLE, "-10.0", "40.0", "RW"));
		properties.put("humidityMeasurementLowThreshold", new ThingPropertyMetadata(
				"Threshold for signaling low relative measured by the object in the specificed unit of measure.", "%",
				ThingDataType.DOUBLE, "0.0", "75.0", "RW"));
		properties.put("pressureMeasurementLowThreshold", new ThingPropertyMetadata(
				"Threshold for signaling low pressure measured by the object in the specificed unit of measure.", "Pa",
				ThingDataType.DOUBLE, "0.0", "75.0", "RW"));
		properties.put("heatMeasurementLowThreshold", new ThingPropertyMetadata(
				"Threshold for signaling low heat consumption measured by the object in the specificed unit of measure.", "J",
				ThingDataType.DOUBLE, "0.0", "75.0", "RW"));
		properties.put("energyMeasurementLowThreshold", new ThingPropertyMetadata(
				"Threshold for signaling low energy consumption measured by the object in the specificed unit of measure.", "kW",
				ThingDataType.DOUBLE, "0.0", "75.0", "RW"));
		properties.put("waterMeasurementLowThreshold", new ThingPropertyMetadata(
				"Threshold for signaling low water consumption measured by the object in the specificed unit of measure.", "m^3",
				ThingDataType.DOUBLE, "0.0", "75.0", "RW"));
		properties.put("gasMeasurementLowThreshold", new ThingPropertyMetadata(
				"Threshold for signaling low gas consumption measured by the object in the specificed unit of measure.","m^3",
				ThingDataType.DOUBLE, "0.0", "75.0", "RW"));
		
		
		properties.put("onoff", new ThingPropertyMetadata("Represents the state of a binary switch object. Identifies whether the binary switch is on or off.", null,
				ThingDataType.BOOLEAN, null, null, "RWE"));
		properties.put("motionDetectionState", new ThingPropertyMetadata("Represents the state of a motion detection object. Identifies whether a motion is detcted or not.", null,
				ThingDataType.BOOLEAN, null, null, "RE"));

	}

	@Override
	public synchronized List<String> getThingProperties() {
		return new ArrayList<String>(properties.keySet());
	}

	@Override
	public synchronized ThingPropertyMetadata getThingPropertyDescription(String property) {
		return properties.get(property);
	}

	@Override
	public synchronized void registerThingPropertyMetadata(String property,
			ThingPropertyMetadata metadata) {
		properties.put(property, metadata);
	}

	@Override
	public synchronized void unregisterThingPropertyMetadata(String property) {
		properties.remove(property);
	}
}
